/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.controller.menu;

import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.constants.ConstantVars;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.mvc.AbstractPlatformController;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.result.BaseRespResult;
import com.je.common.base.result.DirectJsonResult;
import com.je.common.base.spring.SpringContextHolder;
import com.je.common.base.util.MessageUtils;
import com.je.common.base.util.SecurityUserHolder;
import com.je.common.base.util.StringUtil;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.meta.rpc.MetaResourceRpcServiceImpl;
import com.je.meta.rpc.framework.product.ProductRpcService;
import com.je.rbac.exception.MenuException;
import com.je.rbac.service.menu.MenuService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@RestController
@RequestMapping(value = "/je/rbac/menu")
public class MenuController extends AbstractPlatformController {

    @Autowired
    private MenuService menuService;
    @Autowired
    private ProductRpcService productRpcService;
    @Autowired
    private MetaResourceRpcServiceImpl metaResourceRpcService;

    /**
     * 加载首页顶部菜单
     */
    @RequestMapping(value = "/loadHomeTopMenus", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult loadHomeTopMenus(HttpServletRequest request) {
        String departmentId = SecurityUserHolder.getCurrentAccountDepartment().getId();
        String accountId = SecurityUserHolder.getCurrentAccountId();
        boolean enableSaas = SpringContextHolder.getBean("enableSaas");
        String tenantId = "";
        if (enableSaas) {
            tenantId = SecurityUserHolder.getCurrentAccountTenantId();
        }
        String plan = getStringParameter(request, "plan");
        return BaseRespResult.successResult(menuService.loadHomeTopMenus(departmentId, accountId, tenantId, plan));
    }

    /**
     * 加载首页菜单
     */
    @RequestMapping(value = "/loadHomeMenus", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult loadHomeMenus(HttpServletRequest request) {
        String departmentId = "";
        if (SecurityUserHolder.getCurrentAccountDepartment() != null) {
            departmentId = SecurityUserHolder.getCurrentAccountDepartment().getId();
        }
        String accountId = SecurityUserHolder.getCurrentAccountId();
        boolean enableSaas = SpringContextHolder.getBean("enableSaas");
        String tenantId = "";
        if (enableSaas) {
            tenantId = SecurityUserHolder.getCurrentAccountTenantId();
        }
        String plan = getStringParameter(request, "plan");
        JSONTreeNode treeNode = menuService.loadHomeMenus(departmentId, accountId, tenantId, plan);
        return BaseRespResult.successResult(treeNode);
    }

    /**
     * 保存菜单
     *
     * @param param 传入信息
     */
    @RequestMapping(value = "/doSave", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @Override
    public BaseRespResult doSave(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        try {
            menuService.checkFunCodeData(dynaBean);
        } catch (MenuException e) {
            return BaseRespResult.errorResult(e.getMessage());
        }

        DynaBean product = productRpcService.getInfoById(dynaBean.getStr("SY_PRODUCT_ID"));
        if (product != null) {
            dynaBean.setStr("SY_PRODUCT_NAME", product.getStr("PRODUCT_NAME"));
            dynaBean.setStr("SY_PRODUCT_CODE", product.getStr("PRODUCT_CODE"));
        }
        if (StringUtils.isEmpty(dynaBean.getStr("MENU_FUNCTYPE"))) {
            dynaBean.setStr("MENU_FUNCTYPE", "grid");
        }

        request.setAttribute("dynaBean", menuService.doSave(dynaBean));
        //如果菜单选择的是功能，往菜单功能关系表插入对应关系数据
        if ("MT".equals(dynaBean.getStr("MENU_NODEINFOTYPE"))) {
            String menuId = dynaBean.getStr("JE_CORE_MENU_ID");
            String funcCode = dynaBean.getStr("MENU_NODEINFO");
            DynaBean funcBean = metaResourceRpcService.selectOne("JE_CORE_FUNCINFO", NativeQuery.build().eq("FUNCINFO_FUNCCODE", funcCode), "JE_CORE_FUNCINFO_ID");
            String funId = "";
            if (funcBean != null) {
                funId = funcBean.getStr("JE_CORE_FUNCINFO_ID");
            }
            if (!Strings.isNullOrEmpty(funId) && !Strings.isNullOrEmpty(funcCode) && !Strings.isNullOrEmpty(menuId)) {
                DynaBean menuFuncBean = new DynaBean("JE_META_MENUFUNC", false);
                menuFuncBean.setStr("JE_CORE_MENU_ID", menuId);
                menuFuncBean.setStr("JE_CORE_FUNCINFO_ID", funId);
                menuFuncBean.setStr("MENUFUNC_FUNCCODE", funcCode);
                menuFuncBean.setStr("MENUFUNC_ENABLED", dynaBean.getStr("SY_STATUS"));
                commonService.buildModelCreateInfo(menuFuncBean);
                metaResourceRpcService.insert(menuFuncBean);

            }
        }
        return super.doSave(param, request);
    }

    @Override
    @RequestMapping(value = "/doUpdate", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult doUpdate(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        try {
            menuService.checkFunCodeData(dynaBean);
        } catch (MenuException e) {
            return BaseRespResult.errorResult(e.getMessage());
        }

        //处理顶部菜单关联菜单
        String menuId = getStringParameter(request, "JE_CORE_MENU_ID");
        String topMenuId = getStringParameter(request, "MENU_LINK_TOPMENU_ID");
        String topMenuName = getStringParameter(request, "MENU_LINK_TOPMENU_NAME");
        menuService.updateTopMenuRelation(menuId, topMenuId, topMenuName);
        //todo 菜单所属产品发生修改（方案类与平台类切换）；同步清除之前人员关联的权限菜单-关联关系。
        menuService.syncUpdateUserRolePermByProductId(dynaBean);


        DynaBean menuBean = manager.doUpdate(param, request);
        //如果菜单选择的是功能，往菜单功能关系表插入对应关系数据
        if ("MT".equals(menuBean.getStr("MENU_NODEINFOTYPE"))) {
            String funcCode = menuBean.getStr("MENU_NODEINFO");
            DynaBean funcBean = metaResourceRpcService.selectOne("JE_CORE_FUNCINFO", NativeQuery.build().eq("FUNCINFO_FUNCCODE", funcCode), "JE_CORE_FUNCINFO_ID");
            String funId = "";
            if (funcBean != null) {
                funId = funcBean.getStr("JE_CORE_FUNCINFO_ID");
            }
            if (!Strings.isNullOrEmpty(funId) && !Strings.isNullOrEmpty(funcCode) && !Strings.isNullOrEmpty(menuId)) {
                metaResourceRpcService.deleteByTableCodeAndNativeQuery("JE_META_MENUFUNC", NativeQuery.build().eq("JE_CORE_MENU_ID", menuId));
                DynaBean menuFuncBean = new DynaBean("JE_META_MENUFUNC", false);
                menuFuncBean.setStr("JE_CORE_MENU_ID", menuId);
                menuFuncBean.setStr("JE_CORE_FUNCINFO_ID", funId);
                menuFuncBean.setStr("MENUFUNC_FUNCCODE", funcCode);
                menuFuncBean.setStr("MENUFUNC_ENABLED", "1");
                commonService.buildModelCreateInfo(menuFuncBean);
                metaResourceRpcService.insert(menuFuncBean);
            }
        }
        return BaseRespResult.successResult(menuBean.getValues());
    }


    /**
     * 获取菜单树
     *
     * @param param 传入信息
     */
    @RequestMapping(value = "/getTree", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult getTree(BaseMethodArgument param, HttpServletRequest request) {
        String node = param.getNode();
        String rootId = param.getRootId();
        Query query = param.buildQuery();
        commonService.buildProductQuery(query);
        //产品ID
        /*String pdId = getStringParameter(request, "SY_PRODUCT_ID");
        if (Strings.isNullOrEmpty(pdId)) {
            return BaseRespResult.errorResult("请选择产品！");
        }
        query.addCustom("SY_PRODUCT_ID", ConditionEnum.EQ, pdId);*/
        if (StringUtils.isEmpty(node)) {
            node = ConstantVars.TREE_ROOT;
        }
        if (StringUtils.isNotEmpty(rootId)) {
            node = rootId;
        }
        return BaseRespResult.successResult(menuService.getTree(query, node));
    }

    /**
     * 移动菜单
     */
    @RequestMapping(value = "/menuMove", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult menuMove(BaseMethodArgument param, HttpServletRequest request) {
        String toModuleId = getStringParameter(request, "newModuleId");
        String menuId = getStringParameter(request, "JE_CORE_MENU_ID");
        if (Strings.isNullOrEmpty(toModuleId) || Strings.isNullOrEmpty(menuId)) {
            return BaseRespResult.errorResult("9999", "", "请重新选择要转移的模块！");
        }
        //先移动， 再排序
        BaseRespResult baseRespResult = menuService.menuMove(menuId, toModuleId);
        param.setTableCode("JE_CORE_MENU");
        if (!Strings.isNullOrEmpty(param.getStrData())) {
            super.doUpdateList(param, request);
        }
        return baseRespResult;
    }

    /**
     * 删除菜单
     *
     * @param param
     */
    @RequestMapping(value = "/doRemove", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @Override
    public BaseRespResult doRemove(BaseMethodArgument param, HttpServletRequest request) {
        String ids = getStringParameter(request, "ids");
        if (Strings.isNullOrEmpty(ids)) {
            return BaseRespResult.errorResult("9999", "", "请重新选择要删除的菜单！");
        }
        //记录日志，如果日志为空则说明没有数据，直接返回
        int result = menuService.doRemove(ids);
        if (result == 0) {
            return BaseRespResult.errorResult("9999", "", "请重新选择要删除的菜单！");
        }
        //同步删除菜单功能对应关系表数据
        metaResourceRpcService.deleteByTableCodeAndNativeQuery("JE_META_MENUFUNC", NativeQuery.build().in("JE_CORE_MENU_ID", Arrays.asList(ids.split(","))));
        return BaseRespResult.successResult(String.format("%s 条记录和其关联权限删除成功！", result));
    }

    /**
     * 加载菜单提醒
     *
     * @param param 传入信息
     */
    @RequestMapping(value = "/loadBadge", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult loadBadge(BaseMethodArgument param, HttpServletRequest request) {
        String funcCode = getStringParameter(request, "funcCode");
        return BaseRespResult.successResult(DirectJsonResult.buildObjectResult(menuService.loadBadge(funcCode)));
    }

    /**
     * 重新静态化(菜单)
     */
    @RequestMapping(value = "/resetMenuStaticize", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult resetMenuStaticize(BaseMethodArgument param, HttpServletRequest request) {
        return BaseRespResult.successResult("重新静态化成功!");
    }

    /**
     * 对指定菜单授权
     *
     * @param param 参数信息
     */
    @RequestMapping(value = {"/doDevelopPerm"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult doDevelopPerm(BaseMethodArgument param) {
        String pkValue = param.getPkValue();
        if (Strings.isNullOrEmpty(pkValue)) {
            return BaseRespResult.errorResult("传入菜单主键出错!");
        } else {
            return menuService.doDevelopPerm(pkValue);
        }
    }


    @RequestMapping(value = "/move", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult move(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        String id = getStringParameter(request, "id");
        String toId = getStringParameter(request, "toId");
        String place = getStringParameter(request, "place");
        if (StringUtil.isEmpty(id)) {
            return BaseRespResult.errorResult(MessageUtils.getMessage("table.transfer.source.notEmpty"));
        }
        if (StringUtil.isEmpty(toId)) {
            return BaseRespResult.errorResult(MessageUtils.getMessage("table.transfer.target.notEmpty"));
        }
        if (StringUtil.isEmpty(place)) {
            return BaseRespResult.errorResult(MessageUtils.getMessage("table.transfer.target.placePosition"));
        }
        DynaBean sourceBean = menuService.findById(id);
        dynaBean.put("id", id);
        dynaBean.put("toId", toId);
        dynaBean.put("place", getStringParameter(request, "place"));
        DynaBean result = manager.move(dynaBean);
        DynaBean moveAfterBean = menuService.findById(id);
        menuService.checkAndUpdate(sourceBean, moveAfterBean);
        return BaseRespResult.successResult(result, MessageUtils.getMessage("move.success"));
    }

    @RequestMapping(value = "/getMenuScheme", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
    public BaseRespResult getMenuScheme(BaseMethodArgument param, HttpServletRequest request) {
        String id = request.getParameter("id");
        return BaseRespResult.successResult(menuService.getMenuScheme(id));
    }


}
